/* eslint  no-param-reassign: "off" */
import { clickConfig, Config } from '../lib/types';
import { setClickConfig } from '../lib/config';
import { getMCData } from '../lib/dom-data';

// 全局 click 监听
export function addClickListener(clickConf: Config) {
  function eachClickNode(node: Element) {
    let isContinue = true;
    let mcData;
    let currentNode: Element = node;
    while (currentNode.parentNode && isContinue) {
      mcData = getMCData(currentNode.parentNode as Element, clickConf);
      if (mcData) {
        const { config: { clickCount, clickType, count } } = mcData;
        if ((clickCount === 0 || count < clickCount) && clickType !== 1) {
          clickConf.sendClickData && clickConf.sendClickData(mcData, clickConf);
          mcData.config.count += 1;
          if (clickType === 2) {
            isContinue = false;
          }
        }
      }
      if (currentNode.parentNode === document.documentElement) {
        isContinue = false;
      } else {
        currentNode = currentNode.parentNode as Element;
      }
    }
  }

  function clickHandle(event: MouseEvent): void {
    const { target } = event;
    const mcData = getMCData(target as Element, clickConf);
    if (mcData) {
      const { config: { clickCount, clickType, count } } = mcData;
      if (clickCount === 0 || count < clickCount) {
        clickConf.sendClickData && clickConf.sendClickData(mcData, clickConf);
        mcData.config.count += 1;
        // 0 为上报目标节点及其所有父节点的数据，1 为点击元素必须为目标元素才会上报, 2 为仅上报最近的一个节点的数据(上报点击元素，或者最近的一个元素)
        // 0 和 1 类型都是会遍历父节点；2 是上报一个元素之后就结束遍历
        if (clickType === 1) return;
      }
    }
    // 遍历所有父节点
    eachClickNode(target as Element);
  }

  document.body.addEventListener('click', clickHandle, true);
}

// 初始化fish click配置，开启click监听
export default function initClick(options: clickConfig = {}): void {
  const config: Config = setClickConfig(options);
  if (typeof window !== 'object') return;
  addClickListener(config);
}
